import 'package:flutter/material.dart';
import 'package:flutter_assist/ui/base/base_view_model.dart';
import 'package:easy_refresh/easy_refresh.dart';

abstract class ZBaseViewModelList<T> extends ZBaseViewModel {
  static const int pageNumFirst = 1;
  final int pageSize = 20;
  int _currentPageNum = pageNumFirst;
  List<T> data = [];
  bool hasMore = true;

  late EasyRefreshController _refreshController;

  EasyRefreshController get refreshController => _refreshController;

  @override
  void initState() {
    super.initState();
    _refreshController = EasyRefreshController(
      controlFinishRefresh: true,
      controlFinishLoad: true,
    );
    if (autoLoadData) refresh();
  }

  @override
  void dispose() {
    _refreshController.dispose();
    super.dispose();
  }

  void loadData({
    int? pageIndex,
    ValueChanged<List<T>>? onSuccess,
    ValueChanged<List<T>>? onCache,
    ValueChanged<List<String>>? onError,
  });

  void _setData(List<T> data, {bool loadData = true}) {
    _refreshController.finishRefresh(IndicatorResult.success);
    this.data = data;
    if (loadData) setIdle();
  }

  void _setMoreData(List<T> data) {
    _refreshController.finishLoad();
    if (data.isEmpty) {
      _currentPageNum--;
      _refreshController.finishLoad(IndicatorResult.noMore);
      setEmpty();
    } else {
      this.data.addAll(data);
      setIdle();
      // 小于分页的数量，禁止上拉加载更多
      if (data.length < pageSize) {
        _refreshController.finishLoad(IndicatorResult.noMore);
      } else {
        _refreshController.finishLoad(IndicatorResult.success);
      }
    }
  }

  void refresh({
    ValueChanged<List<T>>? onSuccess,
    ValueChanged<List<T>>? onCache,
    ValueChanged<List<String>>? onError,
  }) async {
    this.data.clear();
    setBusy();
    _currentPageNum = pageNumFirst;
    try {
      loadData(
        pageIndex: _currentPageNum,
        onSuccess: (data) {
          _setData(data);
          if (null != onSuccess) onSuccess(data);
        },
        onCache: (data) {
          if (null != onCache) {
            _setData(data);
            onCache(data);
          }
        },
        onError: (data) {
          if (null != onError) onError(data);
          setIdle();
        },
      );
    } catch (e) {
      setIdle();
    }
  }

  void loadMore({
    ValueChanged<List<T>>? onSuccess,
    ValueChanged<List<T>>? onCache,
    ValueChanged<List<String>>? onError,
  }) {
    setBusy();
    try {
      loadData(
        pageIndex: ++_currentPageNum,
        onSuccess: (data) {
          _setMoreData(data);
          if (null != onSuccess) onSuccess(data);
        },
        onCache: (data) {
          if (null != onCache) {
            _setMoreData(data);
            onCache(data);
          }
        },
        onError: (data) {
          _currentPageNum--;
          if (null != onError) onError(data);
          setIdle();
        },
      );
    } catch (e) {
      _currentPageNum--;
      setIdle();
    }
  }
}
